<html>
<head><meta charset="utf-8"><title>piecewise initialization of uninitialized structs · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html">piecewise initialization of uninitialized structs</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="166019842"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166019842" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166019842">(May 19 2019 at 11:45)</a>:</h4>
<p>Am I correct in understanding that the reason that we cannot have piecewise initialization is that getting access to a field requires creating a reference to the field, but we can't uphold the requirements of references because the referred-to value is invalid for the type?</p>
<p>And is it correct that this is one of the motivations behind the <code>&amp;raw</code> syntax?</p>
<p>/cc <span class="user-mention" data-user-id="120791">@RalfJ</span></p>



<a name="166020158"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166020158" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166020158">(May 19 2019 at 11:54)</a>:</h4>
<p>Yes. More precisely "getting access to a field" in the sense of creating a raw pointer to it. Directly writing through a raw pointer field projection like <code>(*p).field = value;</code> should be OK AFAIK (though this has not been discussed as extensively).</p>



<a name="166020604"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166020604" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166020604">(May 19 2019 at 12:06)</a>:</h4>
<p>but there's no way to safely get a raw pointer to the field, if I wanted  to pass it to a C function, right?</p>



<a name="166020622"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166020622" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166020622">(May 19 2019 at 12:07)</a>:</h4>
<p>(this is generally in the context of <a href="https://github.com/rust-lang/rust/issues/53491#issuecomment-493657638" target="_blank" title="https://github.com/rust-lang/rust/issues/53491#issuecomment-493657638">this comment</a>)</p>



<a name="166020680"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166020680" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166020680">(May 19 2019 at 12:09)</a>:</h4>
<p>It's a common Windows API technique to have an uninitialized struct where you've set a length or version field before passing it to a function. If it's OK to use a field projection, then that should be fine.</p>



<a name="166021186"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166021186" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166021186">(May 19 2019 at 12:22)</a>:</h4>
<blockquote>
<p>Yes. More precisely "getting access to a field" in the sense of creating a raw pointer to it. Directly writing through a raw pointer field projection like <code>(*p).field = value;</code> should be OK AFAIK (though this has not been discussed as extensively).</p>
</blockquote>
<p>the problem with this is that it drops the old value in the field</p>



<a name="166021207"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166021207" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166021207">(May 19 2019 at 12:23)</a>:</h4>
<p>so if the type has drop but the field was uninitialized... we got UB, and (unlike the more theoretical issue around creating references to uninitialized fields) this will likely lead to real crashes</p>



<a name="166021214"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166021214" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166021214">(May 19 2019 at 12:23)</a>:</h4>
<blockquote>
<p>It's a common Windows API technique to have an uninitialized struct where you've set a length or version field before passing it to a function. If it's OK to use a field projection, then that should be fine.</p>
</blockquote>
<p>given that these are likely fields of dropless type, writing to a field projection should work</p>



<a name="166021279"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166021279" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166021279">(May 19 2019 at 12:25)</a>:</h4>
<p>but it is a dangerous pattern to use, in case someone reads it and then uses it for their type-with-drop...</p>



<a name="166021330"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166021330" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166021330">(May 19 2019 at 12:26)</a>:</h4>
<p><span class="user-mention" data-user-id="116155">@Jake Goulding</span> ^</p>



<a name="166021477"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166021477" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166021477">(May 19 2019 at 12:30)</a>:</h4>
<p>yup, makes sense, thanks!</p>



<a name="166021482"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166021482" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166021482">(May 19 2019 at 12:30)</a>:</h4>
<p>Mostly collecting knowledge to see if I need to go back and update SO answers</p>



<a name="166022093"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166022093" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166022093">(May 19 2019 at 12:46)</a>:</h4>
<p>thanks for that :)</p>



<a name="166027888"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166027888" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166027888">(May 19 2019 at 15:29)</a>:</h4>
<div class="codehilite"><pre><span></span><span class="k">extern</span><span class="w"> </span><span class="s">&quot;C&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">some_lib_func</span><span class="p">(</span><span class="n">x</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">some_lib_struct_t</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span>: <span class="nc">some_lib_struct_t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">uninitialized</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="n">some_lib_func</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>So, this is UB, right? Since we create a <code>&amp;mut T</code> before making it a <code>*mut T</code>?</p>



<a name="166031503"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166031503" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166031503">(May 19 2019 at 17:06)</a>:</h4>
<p>Yeah but that's not "piecewise", for this the accepted-for-stabilization subset of the MaybeUninit API (soon to be stable in a nightly near you) is sufficient</p>



<a name="166038713"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise%20initialization%20of%20uninitialized%20structs/near/166038713" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/piecewise.20initialization.20of.20uninitialized.20structs.html#166038713">(May 19 2019 at 20:26)</a>:</h4>
<p>ah, good point.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>